import json
import threading
import time
from queue import Queue
import paho.mqtt.client as mqtt
from components.mqtt.base import MQTT_NAME, MQTT_CLIENT_ID, MQTT_USERNAME, MQTT_PASSWORD, MQTT_SERVER, MQTT_PORT
from .receive import order_status, quotation_status

topic_map = {
    # 订阅主题:"函数名-进程数"
    "/{}/Topic/ERP_NEW_ORDER".format(MQTT_NAME): "order_status",
    "/{}/Topic/ERP_NEW_Quotation".format(MQTT_NAME): "quotation_status",
}

for k, v in topic_map.items():
    locals()['q_' + v.split('-')[0]] = Queue()


def deal_msg(q):
    while True:
        if not q.empty():
            data = q.get()
            try:
                eval(data['func'])(data['data'])
            except:
                pass
        else:
            time.sleep(1)


class MQTT(object):
    def __init__(self):
        self.sub_url = '/{}/#'.format(MQTT_NAME)
        self.client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2, MQTT_CLIENT_ID)
        self.client.username_pw_set(MQTT_USERNAME, MQTT_PASSWORD)
        self.client.on_connect = self.on_connect
        self.client.on_message = self.on_message
        self.client.connect(MQTT_SERVER, MQTT_PORT)
        for k, v in topic_map.items():
            v_list = v.split('-')
            v = v_list[0]
            v_num = v_list[1] if len(v_list) > 1 else 1
            for i in range(int(v_num)):
                key = 'p_' + v + '_' + str(i)
                locals()[key] = threading.Thread(target=deal_msg, args=(eval('q_' + v),), daemon=True)
                eval(key).start()

    def on_connect(self, client, userdata, flags, reason_code, properties):
        self.client.subscribe(self.sub_url)

    def on_message(self, client, userdata, msg):
        func = topic_map.get(msg.topic).split('-')[0] if topic_map.get(msg.topic) else None
        if not func:
            return
        eval('q_' + func).put({'func': func, 'data': json.loads(msg.payload.decode('utf-8'))})

    def forever(self):
        self.client.loop_forever()
